/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

/**
 *
 * @author Oscar
 */
public class LambdaGeneralizado {
    //Lambdas:L1,L2,L3,L4
    public double L1,L2,L3,L4;
    
    public static double TOLERANCIA_U;
    
    //Valores predefinidos de los Lambda
    public LambdaGeneralizado() {
        L1=0;L2=1;L3=0.13;L4=0.13;
	TOLERANCIA_U=1e-3;
    }
    //percentiless
    public double fpercentil(double u){
		return L1 + (Math.pow(u,L3) - Math.pow(1 - u,L4))/L2;
    }
    //densidad
    public double fdensidad(double u){
		return L2 / ( L3*Math.pow(u,L3 - 1) + L4*Math.pow(1 - u,L4 - 1) );
    }
    
    //derivada
    public double derivadafpercentil(double u) {
		return 1/fdensidad(u);
    }
    
    
    //verificar si los lambda son validos
    public boolean sonLambdaValidos(){
		if(L2==0) return false;

		if (L3*L4 >= 0){               	    
                    return true;
                }else if ((L3>=1) && (L4<=-1)){
                    return true;
                }else if ((L3<=-1) && (L4>=1)){
                    return true;
                }else if ((L3<0) && (L4>0) && (L4<1)){
                    return false;
                }else if ((L4<0) && (L3>0) && (L3<1)){
                    return false;
                }else if ((L3>-1) && (L3<0) && (L4>=1)){                        //region 5
			if ( (Math.pow((1-L3),(1-L3))*Math.pow((1-L4), (1-L4)))/(Math.pow((L4-L3), (L4-L3))) < -L3/L4 ){ 
				return true;
                        }else{
				return false;
                        }
                }
		else if ((L4>-1) && (L4<0) && (L3>=1)){                         //region 6
			if ( (Math.pow((1-L4), (1-L4))*Math.pow((1-L3), (1-L3)))/(Math.pow((L3-L4), (L3-L4))) < -L4/L3 ){ 
				return true;
                        }else{
				return false;
                        }
                }else                                                            
			return false;
    }

    //Valor crítico
    public double calcularValorCritico(double alfa){
		double u; 
		u=1-alfa;
		return fpercentil(u);
    }
    
    //Calcular el valor de U
    public double calcularU(double x) {
		double a=0,b=1,c=0.5;
		while(b-a > TOLERANCIA_U){
			c = (a+b)/2d;
			if(Math.abs(fpercentil(c)-x) < TOLERANCIA_U){
				return c;
			}
			if((fpercentil(a)-x)*(fpercentil(c)-x) < 0){
				b = c;
			}else{
				a = c;
			}
		}
		return c;
    }
    
    //Calcular U usando Newton Raphson
    public double calcularU_NR(double x) {
		double u=Math.random();
		while(Math.abs(fpercentil(u))>1e-5){
			u = u - (fpercentil(u)-x) / derivadafpercentil(u);
		}
		return u;
    }

}
